﻿using System;
using System.Globalization;
using System.Reflection;
using System.Collections.Generic;

namespace BizElements.Core
{
    internal static class ReflectionUtil
    {
        internal static object CreateInstance(string assemblyName, string fullClassName)
        {
            Assembly asm = Assembly.Load(assemblyName);
            object obj = asm.CreateInstance(fullClassName);
            if (obj == null)
                throw new ArgumentException(string.Format(Messages.ReflectionUtil_CannotFindTypeXInAssemblyY, fullClassName, assemblyName), "fullClassName");

            return obj;
        }

        internal static object GetPublicPropertyValue(object obj, string propertyName)
        {
            PropertyInfo prop = obj.GetType().GetProperty(propertyName);
            return prop.GetValue(obj, null);
        }

        internal static void SetPropertyValue(object obj, string publicPropertyName, object convertibileValue)
        {
            PropertyInfo property = obj.GetType().GetProperty(publicPropertyName);
            object value = ConvertValue(property.PropertyType, convertibileValue);
            property.SetValue(obj, value, null);
        }

        private static object ConvertValue(Type targetType, object value)
        {
            object compatibileValue;
            Type valueType = Nullable.GetUnderlyingType(targetType);
            bool isNullableValueType = (valueType != null);
            if (isNullableValueType)
                compatibileValue = (value != null) ? Convert.ChangeType(value, valueType, CultureInfo.InvariantCulture) : null;
            else
                compatibileValue = Convert.ChangeType(value, targetType, CultureInfo.InvariantCulture);

            return compatibileValue;
        }
    }
}